
var log = function(msg){
	var logWin = $('#logger');
	if(logWin.length == 0){
		var logger = $('<textarea id="logger" />');
			logger.css("width", 320);
			logger.css("height", 400);
			logger.css("display", "block");
			logger.css("right", 0);
			logger.css("top", 0);
			logger.css("position", "absolute");
		    logger.css("border", "solid 1px red");
	    $('body').append(logger);
	}
	
	
	if(arguments.length > 1){
		for(var i=0; i<arguments.length; i++){
			log(arguments[i]);
		}
		return;
	}
	if(window.console){
		window.console.log(msg);
	}else{
		var currentValue = msg + "\n" + $('#logger').attr("value");
		$('#logger').attr("value",  currentValue);
	}
	// NOTE: log to the screen anyway
		var currentValue = msg + "\n" + $('#logger').attr("value");
		$('#logger').attr("value",  currentValue);
}



var testChangingCSSRules = function(){
    var styleSheetsList = document.styleSheets;
    var rules = styleSheetsList[0];
    var str='';
    for(var i in rules){
    	str += i +" - ";
    }
    alert(str);
    var theRules;
	if(rules.cssRules){
		theRules = rules.cssRules
	}else if(rules.rules){
		theRules = rules.rules;
	}else{ 
		return;
	}
	
    str='';
    for(var i=0; i<theRules.length; i++){
    	str += theRules[i] +" - ";
    }
    alert(str);
    
	setTimeout(function(){
		theRules[2].style.border = "2px solid";
		alert(theRules[7].cssText);
	}, 2000);
	
};

/**
 * @class
 */
var JSMXML = function(){
	
};

JSMXML.prototype = {
	
	addEntity: function(elemObj, parentObj){
		var that = this;
		var nodeName = elemObj.context.nodeName;
		var thisElem = elemObj;
		switch(nodeName.toLowerCase()){
			case 'button':
				var label = thisElem.attr("label");
		    	var elem = $('<a href="#">'+ label +'</a>');
		    		elem.addClass("button");
		    		elem.click(function(){
		    			var method = thisElem.attr("onClick");
		    			eval(method);
		    		});
				$(parentObj).append(elem);
			break;
			case 'canvas':
				var width  = parseInt(thisElem.attr("width"));
				var height = parseInt(thisElem.attr("height"));
				//
				var id = thisElem.attr("id");
		    	var elem = $('<div id="'+ id +'"/>');
		    		elem.addClass("canvas");
					if(width) elem.css("width", width);
					if(height) elem.css("height", height);
				$(parentObj).append(elem);
				if(thisElem.children().length > 0){
					var childrenElem = thisElem.children();
						childrenElem.each(function(){
							var parentObj = 
							that.addEntity($(this), elem);
						});
				}
			break;
			case 'jsmxml':
				var jsCodeString = thisElem.html();
					jsCodeString = "<script>\n" + jsCodeString +"\n</script>";
				var scriptTag = $(jsCodeString);
					$('body').append(scriptTag);
			break;
			
			case 'textfield':
				var width  = parseInt(thisElem.attr("width"));
				var height = parseInt(thisElem.attr("height"));
				var id = thisElem.attr("id");
		    	var elem = $('<textarea id="'+ id +'" />');
					elem.css("display", "block");
					elem.css("width", width);
					elem.css("height", height);
		    		elem.addClass("textarea");
				$(parentObj).append(elem); 
			break;
			
			case 'text':
				var width  = parseInt(thisElem.attr("width"));
				var height = parseInt(thisElem.attr("height"));
				var id = thisElem.attr("id");
				var text = thisElem.attr("text");
		    	var elem = $('<span id="'+ id +'" />');
					elem.css("width", width);
					elem.css("height", height);
					elem.html(text);
		    		elem.addClass("text");
				$(parentObj).append(elem); 
			break;
			
			case 'img':
				var width  = parseInt(thisElem.attr("width"));
				var height = parseInt(thisElem.attr("height"));
				var id = thisElem.attr("id");
				var source = thisElem.attr("source");
		    	var elem = $('<img id="'+ id +'" src="'+ source +'"/>');
					elem.css("width", width);
					elem.css("height", height);
		    		elem.addClass("image");
				$(parentObj).append(elem); 
			break;
			
			
			default:
		}
		
		//log(nodeName + ": "+ width +", "+ height);
		
		if(thisElem){
			thisElem.remove();
		}
		log("*** JSMXML.addEntity():"+ nodeName +" ***");
	},
	
	/**
	 * Correct XML string and return a jQuery obejct
	 * 
	 * @param {String} contentString
	 */
	parse: function(contentString){
		var contentString = contentString.split("click").join("onClick");
		var contentObj = $("'"+ contentString +"'");
		// TODO: dispatch event 'onParse'
		return contentObj;
	},
	
	
	
	render: function(childrenElem, view){
		var that = this;
    	$(childrenElem).each(function(){
			that.addEntity($(this), view);
		});
		// TODO: dispatch event 'onContruct'
	}
	
	
};

// Create a singleton
var JSMXML = new JSMXML();



 /**
  * JSMXML initializer
  * 
  * The following function will inspect the DOM and look for all the SCRIPT tag which
  * type is equal to 'text/jsmxml'. JSMXML code and tags must be place inside a 
  * SCRIPT tag of this type. The browser will ignore the code inside this SCRIPT tag.
  * This init function will reparse the code and append the proper visual elements to 
  * the page.
  * 
  * The original SCRIPT tag will be replace by an HTML standard tag.
  * 
  * @example
  * <code>
  * <SCRIPT id="myApp" type="text/jsmxml">
  * 	<Button 
  * 		id="ping" 
  * 		label="My Ping Button" 
  * 		click="alert('ping...')" 
  * 		width="80" 
  * 		height="24"/>
  * </SCRIPT>
  * </code>
  */
jQuery(function($){
    log("*** JSMXML[initializer] ***");
	
	// find SCRIPT tag of type 'text/jsmxml'
    $('script[type="application/jsmxml"]').each(function(){
    	// Create 'application', 'data' and 'domain' objects
		var application = $('<div class="application"/>');  // main application container
		var data = $('<div/>');								// application tags
		var domain = {};									// application methods and properties
    	// parse content
    	application.attr("id",  $(this).attr("id"));
    	application.data("data",  data);
    	application.data("domain",  {});
		application.insertBefore($(this));
    	var contentHTML = $(this).html();
		var contentObj  = JSMXML.parse(contentHTML);
    	data.append(contentObj);
    	// Create visual elements
    	var childrenElem = data.children();
    	JSMXML.render(childrenElem, application);
    	// Remove the SCRIPT tag
		$(this).remove();
    });
    
    // TODO: allow manipulating css rules
	// testChangingCSSRules();
});









